package com.blobfish.fiction.user;

import com.blobfish.fiction.common.base.controller.BaseController;
import com.blobfish.fiction.common.base.exception.GlobalErrorException;
import com.blobfish.fiction.common.model.User;
import com.blobfish.fiction.common.util.RSACoderUtil;
import com.blobfish.fiction.user.constant.UserMessageEnum;
import com.blobfish.fiction.user.service.impl.UserServiceImpl;
import com.blobfish.fiction.user.validator.LoginValidator;
import com.blobfish.fiction.user.validator.RegisterValidator;
import com.jfinal.aop.Before;
import com.jfinal.aop.Inject;
import com.jfinal.core.paragetter.Para;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.redis.Redis;

import java.util.Date;

/**
 * 登录controller
 *
 * @author huangbo
 */
public class LoginController extends BaseController {
    @Inject
    private UserServiceImpl userService;

    /**
     * 登出方法
     */
    public void logout() {
        // 删掉对应cookie
        removeCookie("sign");
        removeCookie("userName");
        redirect("/login/gotoLoginPage");
    }

    public void gotoLoginPage() {
        setAttr("publicKey", PropKit.get("publicKey"));
        render("login.html");
    }

    public void gotoRegisterPage() {
        render("register.html");
    }

    /**
     * 登录方法
     */
    @Before(LoginValidator.class)
    public void doLogin(@Para("")User user) throws Exception{
        String userName = user.getUserName();
        byte[] encodedData = RSACoderUtil.decryptBASE64(user.getPassword());
        byte[] decodedData = RSACoderUtil.decryptByPrivateKey(encodedData, PropKit.get("privateKey"));
        String decodedPass = new String(decodedData);
        User searchUser = userService.getByUserName(userName);
        String password = searchUser.getPassword();
        if (password.equals(decodedPass)) {
            searchUser.setRetryNum(0);
            searchUser.update();
            setCookie("sign", RSACoderUtil.sign(encodedData, PropKit.get("privateKey")), PropKit.getInt("loginSignMaxAgeInSeconds"), true);
            setCookie("userName", userName, PropKit.getInt("loginSignMaxAgeInSeconds"), true);
            Redis.use("master").set("auth:" + userName + ":encodedData", user.getPassword());
            // 登录成功
            renderJson(renderSuccess("登录成功", false));
        } else {
            // 登录失败
            searchUser.setRetryNum(searchUser.getRetryNum() == null ? 1 : searchUser.getRetryNum() + 1);
            searchUser.update();
            throw new GlobalErrorException(UserMessageEnum.USER_NAME_OR_PASSWORD_WRONG);
        }
    }

    /**
     * 注册方法
     * @param user
     */
    @Before(RegisterValidator.class)
    public void doRegister(@Para("") User user) {
        initAddData(user);
        String userName = user.getUserName();
        if (userService.isDuplicateUserName(userName)) {
            throw new GlobalErrorException(UserMessageEnum.USER_NAME_DUPLICATE);
        }
        synchronized (this) {
            if (userService.isDuplicateUserName(userName)) {
                throw new GlobalErrorException(UserMessageEnum.USER_NAME_DUPLICATE);
            }
            userService.add(user);
            renderJson(renderSuccess("注册成功", false));
        }
    }

    private void initAddData(User user) {
        user.setRetryNum(0);
        user.setCreateTime(new Date());
        user.setUpdateTime(new Date());
    }
}
